from typing import Any, Dict, List
from fastapi_amis_admin import admin
from fastapi_amis_admin.admin import (
    AdminApp,
    FieldPermEnum,
    RecentTimeSelectPerm,
    SimpleSelectPerm,
    UserSelectPerm,
)
from fastapi_amis_admin.amis.components import PageSchema, TableColumn, Service, Action
from fastapi_amis_admin.crud.parser import LabelField, PropertyField
from fastapi_amis_admin.models import Field
from fastapi_user_auth.auth.models import User, Role
from fastapi_user_auth.mixins.admin import AuthFieldModelAdmin, AuthSelectModelAdmin
from pydantic import BaseModel
from starlette.requests import Request
from sqlmodel import select
from apps.tower.models import TowerV1
from core.globals import site

@site.register_admin
class TowerApp(admin.AdminApp):
    unique_id = "Tower"
    page_schema = PageSchema(label="Tower应用", icon="fa fa-wordpress")
    router_prefix = "/tower"

    def __init__(self, app: "AdminApp"):
        super().__init__(app)
        self.register_admin(TowerV1Admin)
        

class TowerV1Admin(AuthFieldModelAdmin):
    unique_id = "Tower>TowerV1Admin"
    page_schema = PageSchema(label="TowerV1管理", icon="fa fa-file")
    model = TowerV1
    # 配置模糊搜索字段
    search_fields = [TowerV1.serial_number, TowerV1.base_station_code, TowerV1.town, TowerV1.area, TowerV1.tower_name]
    # 配置列表展示字段
    list_display = [*TowerV1.__fields__.keys()]
    
    # 字段权限，现在将通过动态方法实现
    # 指定不需要权限控制的字段. 
    # perm_fields_exclude = {
    #     FieldPermEnum.VIEW: [*TowerV1.__fields__.keys()],
    #     FieldPermEnum.CREATE: [*TowerV1.__fields__.keys()],
    #     FieldPermEnum.EDIT: [*TowerV1.__fields__.keys()],
    # }
 # 字段权限，指定不需要权限控制的字段.
    perm_fields_exclude = {
        # 全部字段可读,无需验证权限VIEW包含list,filter,read三种操作
        #FieldPermEnum.VIEW: ["__all__"],
        # 创建或更新时无需验证权限的字段 edit包含create与update ,
        FieldPermEnum.EDIT: ["serial_number", "base_station_code", "town", "area", "tower_name"],
    }
    # async def on_update_pre(self, request: Request, obj: BaseModel, **kwargs) -> Dict[str, Any]:
    #     """
    #     更新前的钩子方法，用于根据Casbin权限过滤更新字段
    #     确保用户只能更新其有权限的字段
    #     """
    #     # 获取原始更新数据
    #     data = await super().on_update_pre(request, obj, **kwargs)
        
    #     # 获取当前用户
    #     user = request.user
        
    #     # 使用TowerV1模型的异步filter_update_fields方法过滤更新字段
    #     filtered_data = await TowerV1.filter_update_fields(user, data)
        
    #     return filtered_data
    
    # async def get_perm_fields_exclude(self, request: Request, perm_type: FieldPermEnum) -> List[str]:
    #     """动态获取字段权限，从casbin中获取当前用户的权限规则"""
    #     from core.globals import auth
        
    #     # 获取当前用户
    #     user = request.user
    #     user_id = f"u:{user.username}"
        
    #     # 定义资源类型
    #     resource_type = "field"
        
    #     # 根据权限类型确定操作类型
    #     if perm_type == FieldPermEnum.VIEW:
    #         action = "read"
    #     elif perm_type == FieldPermEnum.EDIT:
    #         action = "update"
    #     elif perm_type == FieldPermEnum.CREATE:
    #         action = "create"
    #     else:
    #         # 默认返回空列表，不排除任何字段
    #         return []
        
    #     # 从casbin中获取用户有该操作权限的所有字段
    #     # 这里假设casbin策略格式为: (user_id, resource_type, field_name, action, "allow")
    #     allowed_fields = []
        
    #     # 获取用户的所有策略
    #     if hasattr(auth, 'enforcer'):
    #         # 获取用户的所有角色
    #         roles = await auth.get_user_roles(user)
    #         # 检查用户自身和所有角色的权限
    #         for subject in [user_id] + [f"r:{role.name}" for role in roles]:
    #             # 获取用户对该资源类型和操作的所有允许的字段策略
    #             policies = auth.enforcer.get_filtered_policy(0, subject, resource_type, "*", action, "allow")
    #             # 提取字段名
    #             for policy in policies:
    #                 # 策略格式: [subject, resource_type, field_name, action, "allow"]
    #                 if len(policy) >= 3:
    #                     field_name = policy[2]
    #                     if field_name != "*" and field_name not in allowed_fields:
    #                         allowed_fields.append(field_name)
        
    #     # 如果用户有admin角色，允许所有字段
    #     if hasattr(user, 'has_requires') and await user.has_requires(request.state.session, roles=["admin"]):
    #         return []
        
    #     # 如果没有配置任何权限规则，使用默认规则
    #     if not allowed_fields:
    #         # 默认规则
    #         default_rules = {
    #             FieldPermEnum.VIEW: ["__all__"],  # 全部可读
    #             FieldPermEnum.EDIT: ["__all__"],  # 只有description可编辑
    #             FieldPermEnum.CREATE: ["__all__"]  # 创建时可编辑这些字段
    #         }
    #         return default_rules.get(perm_type, [])
        
    #     # 计算需要排除的字段（所有字段减去允许的字段）
    #     all_fields = list(TowerV1.__fields__.keys())
    #     excluded_fields = [field for field in all_fields if field not in allowed_fields]
        
    #     return excluded_fields
    
    # async def has_field_permission(self, request: Request, field_name: str, perm_type: FieldPermEnum) -> bool:
   #     """检查用户是否有特定字段的权限"""
        # from core.globals import auth
        
        # # 获取当前用户
        # user = request.user
        # user_id = f"u:{user.username}"
        
        # # 如果用户是管理员，直接返回True
        # if hasattr(user, 'has_requires') and await user.has_requires(request.state.session, roles=["admin"]):
        #     return True
        
        # # 根据权限类型确定操作类型
        # if perm_type == FieldPermEnum.VIEW:
        #     action = "read"
        # elif perm_type == FieldPermEnum.EDIT:
        #     action = "update"
        # elif perm_type == FieldPermEnum.CREATE:
        #     action = "create"
        # else:
        #     return False
        
        # # 检查casbin权限
        # if hasattr(auth, 'enforcer'):
        #     # 检查用户自身权限
        #     if auth.enforcer.enforce(user_id, "field", field_name, action):
        #         return True
            
        #     # 检查用户角色权限
        #     roles = await auth.get_user_roles(user)
        #     for role in roles:
        #         if auth.enforcer.enforce(f"r:{role.name}", "field", field_name, action):
        #             return True
        
        # return False